/*
 *
 *  Copyright (C) 2009 GSyC/LibreSoft
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Roberto Calvo Palomino <rocapal@gsyc.es>
 *
 */


package com.LibreGeoSocial.App;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Hashtable;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;

import com.LibreGeoSocial.Api.Audio;
import com.LibreGeoSocial.Api.GeoNode;
import com.LibreGeoSocial.Api.GeoNodePositionComparator;
import com.LibreGeoSocial.Api.LibreGeoSocial;
import com.LibreGeoSocial.Api.Photo;
import com.LibreGeoSocial.App.Routes.LocationService;
import com.LibreGeoSocial.App.Utils.LocationUtils;



public class PhotoList_LGS extends GenericList  {

	
	private static final int MENU_PHOTOS = Menu.FIRST + 1;
	private static final int MENU_MY_PHOTOS = Menu.FIRST + 2;
	private static final int MENU_UPLOAD_PHOTOS = Menu.FIRST + 3;
	private static final int MENU_PREFERENCE_PHOTOS = Menu.FIRST + 4;

	// Context menu
	private static final int MENU_PRIVACY_PHOTO = Menu.FIRST + 10;
	private static final int MENU_TAGS_PHOTO	= Menu.FIRST + 11;
	private static final int MENU_DELETE_PHOTO  = Menu.FIRST + 12;
	
	
	private static final int DIALOG_NO_PHOTOS = 10;
	private static final int DIALOG_TAGS = 11;
	private static final int DIALOG_AUDIO_RECORD = 12;
	private static final int DIALOG_AUDIO_STOP = 13;
	
	private static final int REQUEST_PREFERENCES = 1; 
	
	PhotoAdapter mAdapter;	
	
	static Photo photo;
	 
	private com.LibreGeoSocial.App.Multimedia.AudioManager aManager;
	
	private Audio myAudio;
	
	private EditText title;
	private EditText body;
	
	private static Integer pagePhoto = 1;
	
	private static PhotoList_LGS pointerObject = null;
	
	private Thread th = null;
	
	@Override  
	public void onCreate(Bundle savedInstanceState) {
		 		
		super.onCreate(savedInstanceState);    
				        
        getData();
        
        pointerObject = this;

	}
	
	private void getData()
	{
		LibreGeoSocial.getInstance().setPagePhoto(pagePhoto);
		
		th = new Thread(){
        	public void run(){ 
        		
        		// Get the data
        		mNodeList = LibreGeoSocial.getInstance().getPhotos(0.0,null);
        		GeoNodePositionComparator comparator = new GeoNodePositionComparator();
        		Collections.sort(mNodeList, comparator);
        		        				        		
        		
        		// init the adapter
        		handler_Adapter.sendEmptyMessage(0);
			}
		};
		

		showProgressDialog("Photos", "Downloading photos", th);
		
	}

	
	/** This adapter 
	 */
	private Handler handler_Adapter = new Handler() {
		@Override
		public void handleMessage(Message msg) {			
			
			initAdapter();
		}
	};
	
	private void initAdapter() 
	{
		if (mAdapter == null )
		{
		
	        mAdapter = new PhotoAdapter(this); 
	        setListAdapter(mAdapter);
	        
	        
	        // Init gestures
	        GesturesHandler gestureHand = new GesturesHandler();        
	        gestureHand.initGestures(this, R.raw.gestures);
	        
	        Hashtable<Object, Object> htGestures = new Hashtable<Object, Object>();
	        
	
			try {
		        
				/* Set the static methods that execute when gesture is recognize */
		        Class c = PhotoList_LGS.class;
		        Method m = c.getDeclaredMethod("GestureNext", (Class[]) null);
				Method m2 = c.getDeclaredMethod("GesturePrevious", (Class[]) null);
				
				htGestures.put((Object)"Previous", m );
				htGestures.put((Object)"Next", m2 );
				
			} catch (NoSuchMethodException e) {			
				e.printStackTrace();
			}        
	
			gestureHand.setGestures(htGestures);
		
		}
		
		// Update the adapter
		mAdapter.notifyDataSetChanged();
		
		// Send message to close the progressDialog
		handler_PDialog.sendEmptyMessage(0);		
		
		// Stop the thread
		th.stop();
	}
	
	public static void GestureNext ()
	{		
		if (pointerObject == null)
			return;
				
		pagePhoto++;
		pointerObject.getData();
		return ;
		
	}
	
	
	
	public static void GesturePrevious ()
	{	
		if (pointerObject == null)
			return;
		
		pagePhoto--;
		pointerObject.getData();
		return;
	}
	
	
	@Override  
	public void onCreateContextMenu(ContextMenu menu, View view,  ContextMenuInfo menuInfo)
	{ 
		super.onCreateContextMenu(menu, view, menuInfo);
		
		menu.add (0, MENU_PRIVACY_PHOTO, 0, "Change Privacy");
		menu.add (0, MENU_TAGS_PHOTO, 0, "Add Tags"); 
		menu.add (0, MENU_DELETE_PHOTO, 0, "Delete Photo");
		
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) 
	{
		
		super.onContextItemSelected(item);
		
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		photo = (Photo) mNodeList.get(info.position); 
		
		switch (item.getItemId()) {
		
			case MENU_DELETE_PHOTO:
				
				LibreGeoSocial.getInstance().deletePhoto(photo.getId());
				mNodeList.remove(info.position);
				updateList();
				
				Toast.makeText(getBaseContext(), 
  					   "Photo deleted correctly!", Toast.LENGTH_LONG).show();
				
				
				break;
				
			case MENU_PRIVACY_PHOTO:
				
				Intent i = new Intent(this,LGS_Preferences.class);				
				startActivityForResult(i,REQUEST_PREFERENCES);
				
				break;
				
			case MENU_TAGS_PHOTO:
				
				showDialog(DIALOG_TAGS);
				
				break;		
		}
		
		return true;
	}
	
	
	
	
	protected void onActivityResult (int requestCode, int resultCode, Intent data) {	 
		
		switch (requestCode) { 
		
	    	case REQUEST_PREFERENCES:
	    		
	    		// User text   
        	    SharedPreferences sharedPreferences = 
        	    	PreferenceManager.getDefaultSharedPreferences(getBaseContext());

        		// Update state in twitter
        		String photoPrivacy = 
        			sharedPreferences.getString (LGS_Preferences.KEY_APP_PHOTO_PRIVACY, "friends");
        		
				if ( LibreGeoSocial.getInstance().setPrivacyNode (photo.getId(), LibreGeoSocial.getInstance().PRIVACY_FRIENDS, true ))
					
	        		Toast.makeText(getBaseContext(), 
	  					   "Upload photo privacy correctly!!", 
	  					   Toast.LENGTH_LONG).show();
				
				else
					
					Toast.makeText(getBaseContext(), 
		  					   "There is a problem with the privacy!", 
		  					   Toast.LENGTH_LONG).show();
	    		
	    		break;
	    		
		}
		
	}
	    		
	    		
	
	@Override
    protected Dialog onCreateDialog(int id) {
        
		
		super.onCreateDialog(id);
    	
		switch (id) {
			
	    	case DIALOG_NO_PHOTOS: 
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("No Photos!")
		        .setMessage("Currently, you can't see friend's pictures . Press 'Menu' and go to 'Upload Photo' to upload your photos!")
		        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) { 

		            	
		            }
		        })
		        .create();
			

	    	case DIALOG_TAGS:
	    		
	    		LayoutInflater factory = LayoutInflater.from(this);
	    		final View textEntryView = factory.inflate(R.layout.state, null);
	    		
	    		final EditText edit = (EditText) textEntryView.findViewById (R.id.txtstate);
	    		edit.setText("");
	    		
	    		final TextView text = (TextView) textEntryView.findViewById (R.id.state_view);
	    		text.setText("The tags must be separated by spaces");
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("Set Tags")
		        .setView(textEntryView)
		        .setPositiveButton("Tagging", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		            	
		            	
		            	if (LibreGeoSocial.getInstance().setTags( photo.getId(), 
		            										  edit.getText().toString()))
		            	{
		            		
		            		Toast.makeText(getBaseContext(), 
			     					   "Node tagged correctly!", 
			     					   Toast.LENGTH_LONG).show();
		            		
		            	}
		               	else
		            	{
		            		Toast.makeText(getBaseContext(), 
			     					   "Error while the status was setted: " + 
			     					   LibreGeoSocial.getInstance().getLastMsgServer(), 
			     					   Toast.LENGTH_LONG).show();
		            	}
		            	
		            	
		            }
		        })
		        .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		
		                /* User clicked cancel so do some stuff */
		            }
		        })
		        .create();
		        
		        
	    	case DIALOG_AUDIO_RECORD:	    		
	    		
	    		aManager = new com.LibreGeoSocial.App.Multimedia.AudioManager(this);
	    		
	    		LayoutInflater factory2 = LayoutInflater.from(this);
	    		final View textEntryView2 = factory2.inflate(R.layout.note, null);
	    		
	    		title = (EditText) textEntryView2.findViewById (R.id.txtTitle);
	    		body = (EditText) textEntryView2.findViewById (R.id.txtBody);
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("Recording Audio")
		        .setView(textEntryView2)
		        .setPositiveButton("Record", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		            	
		                /* User clicked OK so do some stuff */ 
		            	
		            	myAudio = new Audio  (null, 
		            						  title.getText().toString(), 
		            						  body.getText().toString(),
		            						  "", "",
		            						  LocationService.getCurrentLocation().getLatitude(),
		            						  LocationService.getCurrentLocation().getLongitude(),
		            						  LocationService.getCurrentLocation().getAltitude(),
		            						  null, null);
		            	
		            	
		            	
		                 doRecording (title.getText().toString().replace(" ", "_"));		                 
		            
		            	
		            }
		        })
		        .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		
		                /* User clicked cancel so do some stuff */
		            }
		        })
		        .create();
  
		        
		        
	    	case DIALOG_AUDIO_STOP: 
	    		
	    		
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("")
		        .setMessage("The recording is in progress. Press the button to stop the recording")
		        .setPositiveButton("Stop", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) { 
		            	
		            	// Stop recording
		            	aManager.stopRecording();
		            	
		            	// Save path to audio file
		            	myAudio.setPath(aManager.getPath());
		            	
		            	// Upload file audio.
		            	LibreGeoSocial.getInstance().uploadAudio(myAudio);
		            	
		            	File f = new File(myAudio.getPath());
		            	f.delete();
		            	
		            }
		        })
		        .create();
		    
    	
    	}
    	
		return super.onCreateDialog(id);
    
	}
	
	private void doRecording (String name)
	{
		
		aManager.setName(name);
		aManager.startRecording();
		
		showDialog(DIALOG_AUDIO_STOP);
	}
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	
        super.onCreateOptionsMenu(menu);
        menu.add(0, MENU_PHOTOS, 0, "Show All Photos")
        		.setIcon(R.drawable.mundo)
                .setAlphabeticShortcut('A');
                 
        menu.add(0, MENU_MY_PHOTOS, 0, "Show My Photos")
				.setIcon(R.drawable.image_48)
		        .setAlphabeticShortcut('B');
        
        menu.add(0, MENU_UPLOAD_PHOTOS, 0, "Upload Photo")
				.setIcon(R.drawable.camera)
		        .setAlphabeticShortcut('C');    
        
        menu.add(0, MENU_PREFERENCE_PHOTOS, 0, "Audio")
				.setIcon(R.drawable.spanner_48)
		        .setAlphabeticShortcut('D');
		        
        return true;
    }
	
    @Override
    public boolean onOptionsItemSelected (MenuItem item) {
    	
    	switch (item.getItemId()) {
    	
    		case MENU_PHOTOS:
    		
    			mNodeList = LibreGeoSocial.getInstance().getPhotos(0.0,null);
    			updateList();
    			break;
    			
    		case MENU_MY_PHOTOS:
    			
    			mNodeList = LibreGeoSocial.getInstance().getMyPhotos();  	
    			updateList();
    			break;
    			
    		case MENU_UPLOAD_PHOTOS:
    			
    			Intent i = new Intent(this, UploadPhoto.class);    			
    			startActivity(i); 
    			
    		case MENU_PREFERENCE_PHOTOS: //AUDIO
    			
    			mNodeList = LibreGeoSocial.getInstance().getAudios(0.0,null);
    			updateList();
    			
    			showDialog(DIALOG_AUDIO_RECORD);
    			
    			
    			
    	}
    	


    	
    	return super.onOptionsItemSelected(item);
    }
	
    private void updateList ()
    {
		GeoNodePositionComparator comparator = new GeoNodePositionComparator();
		Collections.sort(mNodeList, comparator);
    	mAdapter.notifyDataSetChanged();    	
    }
    
    protected void onListItemClick(ListView l, View v, int position, long id) {
    	
    	GeoNode node = mNodeList.get(position); 
    	
    	if ( Photo.class.isInstance(node) )  
    	{
	    	Photo myphoto = (Photo) mNodeList.get(position);
	
	    	Intent i = new Intent(this, PhotoCard.class);
	    	
	    	i.putExtra("latitude",myphoto.getLatitude());
	    	i.putExtra("longitude",myphoto.getLongitude());
	    	i.putExtra("distance", getDistance(myphoto.getLatitude(), myphoto.getLongitude(),myphoto.getLocation()).toString());
	    	i.putExtra("url",myphoto.getUrl());
	    	i.putExtra("description", myphoto.getDescription());
	    	i.putExtra("name", myphoto.getName());
	    	i.putExtra("since", myphoto.getSince());
	    	i.putExtra("author", myphoto.getUploader());
	    	
	    	startActivity(i);
    	}
    	
    	else if ( Audio.class.isInstance(node) )  
    	{
    		
    		//TODO: show bar progress
    		
    		Audio myaudio = (Audio) mNodeList.get(position);
    		
    		// Downloading
    		InputStream is = LibreGeoSocial.getInstance().getAudio(myaudio.getUrl());
    		aManager = new com.LibreGeoSocial.App.Multimedia.AudioManager(this);
    		
    		aManager.saveAudio (is,"tmpaudio");
    		
    		// Playing audio    		
    		aManager.startPlayer();
    		
    	}
    	    	
    	
	}
	
    private static String getDistance(Double longitude, Double latitude, Location location){
    	String distString = null;
        
		if ( latitude==-1.0 && 
			 longitude==-1.0)
		{
			distString = "Unknow Location";
		}
		else
		{
			
			// Calculate distance
			float dist = LocationUtils.calculateDistance (LocationService.getCurrentLocation(), 
														  location);
			
			distString = LocationUtils.displayDistance(dist, LocationUtils.AUTO);
		}
		return distString;
    }
     
	public static class PhotoAdapter extends BaseAdapter {

		private Context mContext;
		
		public PhotoAdapter(Context c) {
            mContext = c;
        }

		public int getCount() {
			
			return mNodeList.size();
		}

		public Object getItem(int position) {
			
			return position;
		}

		public long getItemId(int position) {
			
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			
			View view;
			
	        if (convertView == null) {
	            // Make up a new view
	            LayoutInflater inflater = (LayoutInflater) mContext
	                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	            view = inflater.inflate(R.layout.generic_list, null);
	            
	        } else {
	            // Use convertView if it is available
	            view = convertView;
	            
	        }
			
	        GeoNode node = mNodeList.get(position); 
	        
	        TextView t = (TextView) view.findViewById(R.id.title);
	        TextView t2  = (TextView) view.findViewById(R.id.owner);
	        
	        String distString = null;
	        
	        distString = getDistance(node.getLatitude(), node.getLongitude(),node.getLocation());
	        
			/*if ( node.getLatitude()==-1.0 && 
				 node.getLongitude()==-1.0)
			{
				distString = "Unknow Location";
			}
			else
			{
				
				// Calculate distance
				float dist = LocationUtils.calculateDistance (LocationService.getCurrentLocation(), 
															  node.getLocation());
				
				distString = LocationUtils.displayDistance(dist, LocationUtils.AUTO);
			}
			*/
			
	        if ( Photo.class.isInstance(node) )  
	        {
	        
	        	Photo myphoto = (Photo) mNodeList.get(position);
	        
	        	ImageView img = (ImageView) view.findViewById(R.id.image);
	        	img.setImageBitmap(myphoto.getBitmapImageThumb());
	        	
	        	t.setText(myphoto.getName());
	        	t2.setText("Dist: " + distString + "\n" + myphoto.getDescription());
	        }	      

			
			return view;
	        
		}

	}



}
